﻿#region << 版 本 注 释 >>
/*----------------------------------------------------------------
 * 版权所有 (c) 2022 北京超维景生物科技有限公司 保留所有权利。
 * CLR版本：4.0.30319.42000
 * 文件名：Kernel
 * 
 * 创建者：huangyang
 * 电子邮箱：huangyang@tvscope.cn
 * 创建时间：2023/2/9 10:29:19
 * 版本：V1.0.0
 * 描述：
 *
 * ----------------------------------------------------------------
 * 修改人：
 * 时间：
 * 修改说明：
 *
 * 版本：V1.0.1
 *----------------------------------------------------------------*/
#endregion << 版 本 注 释 >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ImageK.Java;
using ImageK.Process;

namespace ImageK
{
    /// <summary>
    /// This class represents a color look-up table.
    /// </summary>
    public class LookUpTable
    {
        private int width, height;
        private byte[] pixels;
        private int mapSize = 0;
        private ColorModel cm;
        private byte[] rLUT, gLUT, bLUT;

        /** Constructs a LookUpTable object from an AWT Image. */
        public LookUpTable(Image img)
        {
            //todo:
            // PixelGrabber pg = new PixelGrabber(img, 0, 0, 1, 1, false);
            // try
            // {
            //     pg.grabPixels();
            //     cm = pg.getColorModel();
            // }
            // catch (Exception e) { };
            // getColors(cm);
        }

        /** Constructs a LookUpTable object from a ColorModel. */
        public LookUpTable(ColorModel cm)
        {
            this.cm = cm;
            getColors(cm);
        }

        void getColors(ColorModel cm)
        {
            if (cm is IndexColorModel) {
                IndexColorModel m = (IndexColorModel)cm;
                mapSize = m.getMapSize();
                rLUT = new byte[mapSize];
                gLUT = new byte[mapSize];
                bLUT = new byte[mapSize];
                m.getReds(rLUT);
                m.getGreens(gLUT);
                m.getBlues(bLUT);
            }
        }

        public int getMapSize()
        {
            return mapSize;
        }

        public byte[] getReds()
        {
            return rLUT;
        }

        public byte[] getGreens()
        {
            return gLUT;
        }

        public byte[] getBlues()
        {
            return bLUT;
        }

        public ColorModel getColorModel()
        {
            return cm;
        }


        /** Returns <code>true</code> if this is a 256 entry grayscale LUT.
            @see ij.process.ImageProcessor#isColorLut
        */
        public bool isGrayscale()
        {
            bool isGray = true;

            if (mapSize < 256)
                return false;
            for (int i = 0; i<mapSize; i++)
                if ((rLUT[i] != gLUT[i]) || (gLUT[i] != bLUT[i]))
                    isGray = false;
            return isGray;
        }

        public void drawColorBar(Graphics g, int x, int y, int width, int height)
        {
            if (mapSize == 0)
                return;
            ColorProcessor cp = new ColorProcessor(width, height);
            double scale = 256.0/mapSize;
            for (int i = 0; i<256; i++)
            {
                int index = (int)(i/scale);
                cp.setColor(Color.FromArgb(rLUT[index]&0xff, gLUT[index]&0xff, bLUT[index]&0xff));
                cp.moveTo(i, 0); cp.lineTo(i, height);
            }
            g.DrawImage(cp.createImage(), x, y);
            Pen pen = new Pen(Color.Black);
            g.DrawRectangle(pen, x, y, width, height);
        }



        public void drawUnscaledColorBar(ImageProcessor ip, int x, int y, int width, int height)
        {
            ImageProcessor bar = null;
            if (ip is ColorProcessor)
                bar = new ColorProcessor(width, height);
            else
                bar = new ByteProcessor(width, height);
            if (mapSize == 0)
            {  //no color table; draw a grayscale bar
                for (int i = 0; i < 256; i++)
                {
                    bar.setColor(Color.FromArgb(i, i, i));
                    bar.moveTo(i, 0); bar.lineTo(i, height);
                }
            }
            else
            {
                for (int i = 0; i<mapSize; i++)
                {
                    bar.setColor(Color.FromArgb(rLUT[i]&0xff, gLUT[i]&0xff, bLUT[i]&0xff));
                    bar.moveTo(i, 0); bar.lineTo(i, height);
                }
            }
            ip.insert(bar, x, y);
            ip.setColor(Color.Black);
            ip.drawRect(x-1, y, width+2, height);
        }

        public static ColorModel createGrayscaleColorModel(bool invert)
        {
            byte[] rLUT = new byte[256];
            byte[] gLUT = new byte[256];
            byte[] bLUT = new byte[256];
            if (invert)
                for (int i = 0; i < 256; i++)
                {
                    rLUT[255 - i] = (byte)i;
                    gLUT[255 - i] = (byte)i;
                    bLUT[255 - i] = (byte)i;
                }
            else
            {
                for (int i = 0; i < 256; i++)
                {
                    rLUT[i] = (byte)i;
                    gLUT[i] = (byte)i;
                    bLUT[i] = (byte)i;
                }
            }
            return (new IndexColorModel(8, 256, rLUT, gLUT, bLUT));
        }
	}
}
